package com.evildog.workspace.common.util;


import com.evildog.workspace.common.consts.CommonConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;

/**
 * 获取IP的工具类
 *
 * @author evildog
 */
@Slf4j
public class IpUtil {

    /**
     * 需要获取的ip头
     */
    private static List<String> checkHeaders = new ArrayList<>(Arrays.asList(
            CommonConst.GATEWAY_IP_HEADER,
            "X-Real-IP",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP"
    ));

    public static String getRealIp(HttpServletRequest request) {
        String ip = "";
        try {
            ip = request.getHeader("X-Forwarded-For");
            if (isValidIp(ip)) {
                return getProxyIp(ip);
            }

            ip = getIp(checkHeaders, request::getHeader);
            if (isValidIp(ip)) {
                return ip;
            }

            // 默认
            return request.getRemoteAddr();
        } catch (Exception e) {
            log.error("获取ip错误:", e);
        }

        return ip;
    }

    public static String getRealIp(ServerHttpRequest request) {
        String ip = "";
        try {
            HttpHeaders headers = request.getHeaders();

            ip = headers.getFirst("X-Forwarded-For");
            if (isValidIp(ip)) {
                return getProxyIp(Objects.requireNonNull(ip));
            }

            ip = getIp(checkHeaders, headers::getFirst);
            if (isValidIp(ip)) {
                return ip;
            }

            // 默认方式
            return Objects.requireNonNull(request.getRemoteAddress())
                    .getAddress().getHostAddress();
        } catch (Exception e) {
            log.error("获取ip错误:", e);
        }


        return ip;
    }

    private static String getProxyIp(String ip) {
        // 多次反向代理后会有多个ip值，第一个 ip 才是真实 ip
        int index = ip.indexOf(",");
        if (index != -1) {
            return ip.substring(0, index);
        } else {
            return ip;
        }
    }

    /**
     * 校验IP
     */
    private static boolean isValidIp(String ip) {
        return StringUtils.hasText(ip) && !"unknown".equalsIgnoreCase(ip) && !"0:0:0:0:0:0:0:1".equals(ip);
    }

    private static String getIp(List<String> headers, Function<String, String> function) {
        return headers.stream().map(function).filter(IpUtil::isValidIp).findFirst().orElse("");
    }

}
